﻿using Dyao.Book.Entity;
using Dyao.Book.Repository.Abstractions;
using System.Linq.Expressions;

namespace Dyao.Book.Repository.Repositories
{
    using Foundation.Replacement;

    public class BookRepository : DataRepository<BookEntity>, IBookRepository
    {
        /// <inheritdoc cref="IBookRepository.BulkUpdateAsync"/>
        public new Task BulkUpdateAsync(IEnumerable<BookEntity> entities, Expression<Func<BookEntity, object>> updateSelector, CancellationToken cancellationToken = default)
        {
            return base.BulkUpdateAsync(entities, op =>
            {
                op.ColumnPrimaryKeyExpression = key => new { key.ID };
                op.IncludeOnUpdateExpression = updateSelector;
            }, cancellationToken);
        }

        /// <inheritdoc cref="IBookRepository.GetListByTitleAsync"/>
        public async Task<List<BookEntity>> GetListByTitleAsync(List<string> titles, CancellationToken cancellationToken)
        {
            if (titles.IsNullOrEmpty())
                return Enumerable.Empty<BookEntity>().ToList();
            var query = this.GetQueryable()
                .Where(b => titles.Contains(b.Title));

            return await query.ToListAsync(cancellationToken);
        }

        /// <inheritdoc cref="IBookRepository.GetListByTitleAsync"/>
        public async Task<List<T>> GetListByIdsAsync<T>(List<string> ids, Expression<Func<BookEntity, T>> selector, CancellationToken cancellationToken)
        {
            if (ids.IsNullOrEmpty())
                return Enumerable.Empty<T>().ToList();

            var query = this.GetQueryable()
                .Where(b => ids.Contains(b.ID))
                .Select(selector);

            return await query.ToListAsync(cancellationToken);
        }

        /// <inheritdoc cref="IBookRepository.GetByIdAsync"/>
        public async Task<BookEntity> GetByIdAsync(string id, CancellationToken cancellationToken)
        {
            var query = this.GetQueryable()
                .Where(b => b.ID == id);

            return await query.FirstOrDefaultAsync(cancellationToken);
        }

        /// <inheritdoc cref="IBookRepository.GetAllListAsync"/>
        public async Task<List<T>> GetAllListAsync<T>(Expression<Func<BookEntity, T>> selector, CancellationToken cancellation)
        {
            var query = this.GetQueryable()
                .Select(selector);

            return await query.ToListAsync(cancellation);
        }
    }
}
